package com.only4play.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * @author liyuncong
 * @version 1.0
 * @file FTPUtil
 * @brief Ftp工具类
 * @details Ftp工具类
 * @date 2024-03-25
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                     NAME               DESCRIPTION
 * 2024-03-25               liyuncong          Created
 */

@Slf4j
public class FTPUtil {

    private final String host;
    private final Integer port;
    private final String userName;
    private final String password;

    public FTPUtil(String host, int port, String userName, String password) {
        this.host = host;
        this.port = port;
        this.userName = userName;
        this.password = password;
    }

    public FTPClient getFTPClient() {
        return getFTPClient(this.host, this.userName, this.password, this.port);
    }
    public static FTPClient getFTPClient(
        String ftpHost, String ftpUserName, String ftpPassword, int ftpPort
    ) {
        FTPClient ftpClient;
        try {
            ftpClient = new FTPClient();
            ftpClient.setConnectTimeout(60000);       //连接超时为60秒
            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                ftpClient.disconnect();
            }
        } catch (IOException e) {
            log.error("FtpUtils getFTPClient异常", e);
            throw new RuntimeException(e);
        }
        return ftpClient;
    }


    public boolean upload(String remotePath, String filename, byte[] data) {
        final FTPClient client = this.getFTPClient();
        if (client == null) {
            return false;
        }
        try {
            return this.upload(remotePath, filename, new ByteArrayInputStream(data));
        } catch (Exception ex) {
            log.error(ex.getLocalizedMessage(), ex);
            return false;
        }
    }

    public boolean upload(String ftpPath, String fileName, InputStream input) {
        boolean success = false;
        FTPClient ftpClient = null;
        try {
            int reply;
            ftpClient = this.getFTPClient();
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                return success;
            }
            ftpClient.setControlEncoding("UTF-8"); // 中文支持
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();

            if (!ftpClient.changeWorkingDirectory(ftpPath)) {
                //如果目录不存在创建目录
                log.error("ftp目录 不存在，创建 path=" + ftpPath);
                String[] dirs = ftpPath.split("/");
                String tempPath = "";
                for (String dir : dirs) {
                    if (null == dir || dir.isEmpty()) continue;
                    tempPath += "/" + dir;
//                    System.out.println("ftp目录=tempPath=" + tempPath);
                    if (!ftpClient.changeWorkingDirectory(tempPath)) {
                        if (!ftpClient.makeDirectory(tempPath)) {
                            return false;
                        } else {
                            ftpClient.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            ftpClient.storeFile(fileName, input);

            input.close();
            ftpClient.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }


    public boolean download(String ftpPath, String fileName, String downloadFilePath) {
        FTPClient ftpClient = null;
        OutputStream os = null;
        try {
            int reply;
            ftpClient = this.getFTPClient();
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                return false;
            }
            ftpClient.setControlEncoding("UTF-8"); // 中文支持
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(ftpPath);
            os = Files.newOutputStream(Paths.get(downloadFilePath));
            boolean retrieved = ftpClient.retrieveFile(fileName, os);
            os.close();
            ftpClient.logout();
            return retrieved;
        } catch (IOException e) {
            log.error("FtpUtils下载文件异常", e);
            return false;
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
    }

    public boolean isExist(String ftpPath, String fileName) {
        FTPClient ftpClient = null;
        try {
            ftpClient = getFTPClient();
            int reply;
            ftpClient = this.getFTPClient();
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                throw new RuntimeException("连接ftp异常");
            }
            ftpClient.setControlEncoding("UTF-8"); // 中文支持
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(ftpPath);
            boolean isExist = ftpClient.listFiles(fileName).length > 0;
            ftpClient.logout();
            return isExist;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
    }

    public static boolean deleteFile(
        String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
        String filePath, String filename
    ) {
        FTPClient ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
        boolean flag = false;
        if (ftpClient != null) {
            try {
                ftpClient.changeWorkingDirectory(filePath);
                ftpClient.dele(filename);
                flag = true;
                ftpClient.logout();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (ftpClient.isConnected()) {
                    try {
                        ftpClient.disconnect();
                    } catch (IOException ioe) {
                    }
                }
            }
        }
        return flag;
    }
}
